home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
language
/
forth
/
jx4a0317.lzh
/
JAX4TH.I
< prev
next >
Wrap
Text File
|
1994-05-17
|
14KB
|
432 lines
*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*
* *
* jax4th.i ... shared includes for JAX4TH *
* *C* COPYRIGHT 1991, 1993 jack j. woehr *
* jax@well.UUCP JAX on GEnie SYSOP, RCFB (303) 278-0364 *
* *
*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*;*
*--- Register Equates
dsp equr a7 ; data stack pointer, ptr to "rest of stack"
rp equr a6 ; return pointer
ip equr a5 ; instruction pointer
bp equr a4 ; base pointer to local data space
np equr a3 ; next pointer, points to copy of NEXT in local image
cp equr a2 ; points to base of resident code space
tos equr d7 ; top of stack is "cached"
dp equr d6 ; local dictionary pointer
ap equr d5 ; allocation pointer to data space
*--- Some Other Equates
eol equ $0a ; end of line character
charsize equ 1 ; size of a char in address units
cellsize equ 4 ; cellsize of our 32-bit Forth
numthreads equ 4 ; number threads in a voc
vocwidth equ ((numthreads*cellsize)+cellsize+cellsize)
; thread0/thread1/thread2/thread3/voclink/nameptr
numvocs equ 8 ; max vocs in search order
contextsize equ numvocs*cellsize ; CONTEXT voc ptr array size
namebit equ $80 ; mask for start and end of name field
immedbit equ $40 ; mask for IMMEDIATE word's count byte
dirtybit equ $80000000 ; mask for a BUFFER to be SAVEd
unheader equ -1 ; cell-size mask for headerless def
maxncount equ $1F ; max char count in a name header
maxnchar equ $7F ; max ascii value of a name character
kernbit equ $80000000 ; mask for kernel token
doflag equ $FFFFFFFF ; compiler security flag
ifflag equ $7FFFFFFF ; compiler security flag
beginflag equ $3FFFFFFF ; compiler security flag
forflag equ $1FFFFFFF ; compiler security flag
whileflag equ $0FFFFFFF ; compiler security flag
elseflag equ $07FFFFFF ; compiler security flag
compflag equ $00FFFFFF ; a general purpose mask
countstrsize equ $FF ; longest counted string
tibsize equ $100 ; do signed count bytes exist?
inputsize equ $80 ; all we ACCEPT in TIB for now
argarraysize equ cellsize*$0D ; regs for function calls, D0-D6/A0-A5
emitbufsize equ $100 ; size of stored ouput strings
dstampsize equ cellsize*3 ; AmigaDOS DateStamp
readbuffsize equ $1000 ; size of a file read buffer
blockoversize equ 4 ; bytes in BLOCK overhead
rawblocksize equ $400 ; bytes in a BLOCK itself
blocksize equ rawblocksize+blockoversize ; size of a block buffer with overhead
numblockbuffs equ 2 ; number of BLOCK buffers we'll support
blockbuffsize equ blocksize*numblockbuffs ; two block buffers
charsperline equ 64 ; characters per line of a screen file
linesperscreen equ rawblocksize/charsperline ; lines in a SCR
*--- Macros
;--- Stack Manipulation
pshdsp macro ; move cached top of stack to data stack.
move.l tos,-(dsp) ; this by itself is DUP
endm
push macro ; move tos to dsp and cache arg \1 as tos
pshdsp
move.l \1,tos
endm
popdsp macro ; restore top of stack from data stack.
move.l (dsp)+,tos ; this by itself is DROP
endm
pop macro ; move tos to \1 and restore tos from dsp
move.l tos,\1
popdsp
endm
rpush macro ; push \1 to return stack
move.l \1,-(rp)
endm
rpop macro ; pop return stack to \1
move.l (rp)+,\1
endm
tonext macro ; compiled inline at end of code words
jmp (np) ; NP will be set to NEXT
endm
nest macro ; inline execution engine for colon definition
rpush ip ; save the instruction pointer,
lea.l *+6(pc),ip ; load IP with this word's addr list base addr
tonext ; jump next.
endm
;--- Calling DOS and Exec for Kernel Startup Routines
callos macro ; call Amiga lib when libptr in A6
jsr _LVO\1(rp) ; jump to offset from lib ptr
endm
callamy macro ; \1 Routine \2 Lib Save RP when using lib ptr
move.l rp,-(sp) ; save a6
move.l #\2lib,rp ; get the lib ptr var address
move.l 0(bp,rp.l),rp ; get the lib ptr itself into A6
callos \1 ; call the routine
move.l (sp)+,rp ; discard lib pointer, restore RP
push d0 ; save return val from call
endm
;--- Some General Tools for User-Specified OS Calls
savereg macro ; save the Forth engine except the stack & lib pointer and TOS
movem.l cp-rp/ap-dp,-(sp)
endm
getreg macro ; restore the Forth engine except stack & lib pointers & TOS
movem.l (sp)+,ap-dp/cp-rp
endm
getarg macro ; load all except stack ptr, tos and lib ptr for an OS call
push #argarray
movem.l 0(bp,d7.l),d0-d6/a0-a5
popdsp
endm
;----------------------------------------------------------------------------;
; Kernel variables are declared at the end of this file. Since ! and @ ;
; will convert offsets in the data segment to absolute addresses transparent ;
; to the user, the DOCREATE and DOCONSTANT engines are identical. ;
;----------------------------------------------------------------------------;
docreat macro ; compile dataseg offset + execution engine
push #\1 ; push dataseg offset from jax4th.i
tonext ; and go NEXT
endm
;--- Constants in the shared segment use the same execution engine.
doconst macro ; compile literal + execution engine
push #\1 ; \1 is the constant value
tonext ; return to Forth
endm
;---------------------------------------------------------------;
; And Vocabularies use this one. The voc ptr is a DSeg-relative ;
; address to be deref'ed like all data access in this Forth. ;
;---------------------------------------------------------------;
dovoc macro ; assemble execution engine for a vocabulary
move.l #contextarray,d0
move.l #\1,0(bp,d0.l) ; CONTEXT[0] <- DSeg.forthvoc
tonext ; return to Forth
endm
* DOES and UNDOES aren't quite right yet, the stack is messy
* maybe a rp -> a0 ip -> rp a0 ->ip? foof.
* dodoes macro ; execute hilevel interpreter compiled with does>
* rpush (ip) ; push the ip
* move.l (sp)+,ip ; new ip is waiting on the system stack
* next ; jump next
* endm
* undoes macro ; return from hilevel to code level
* rpush ip ; hide subroutine return address
* move.l (sp)+,ip ; pop system stack to restore ip
* rts ; return
* endm
;--- Stores & Fetches
sto macro ; addr in tos, data in @sp
move.l (sp)+,0(bp,tos.l)
endm
fet macro ; addr in tos, returns data in tos
move.l 0(bp,tos.l),tos
endm
;--- Block Moves
* There is something that should be noted here about byte and
* block moves. CMOVE> actually moves to the left. CMOVE moves
* to the right. The ">" in CMOVE is intended to signify that
* the *data* is moving left (low mem) to right (high mem).
* I have found this confusing!
lindex macro ; set up indices for data to move left progressing right
movea.l bp,a0 ; base address of data segment
movea.l bp,a1
adda.l (dsp)+,a1 ; destination
adda.l (dsp)+,a0 ; source
endm
rindex macro ; set up indices for data to move right progressing left
lindex
adda.l tos,a0 ; add count for backwards move
adda.l tos,a1
endm
dmov macro ; prepare to move to prevent overlap
move.l 4(dsp),d0 ; get source
cmp.l (dsp),d0 ; destination greater than source?
endm ; LT if DEST > SRC
;--- Dictionary Alignment ... these are all forward aligns
walin macro ; align contents of Dreg to next word boundary
moveq.l #0,d0 ; obviously, \1 can't be d0
lsr.l #1,\1
addx.l d0,\1
lsl.l #1,\1
endm
lalin macro ; align contents of Dreg to next lword boundary
moveq.l #0,d0 ; obviously, \1 can't be d0
lsr.l #1,\1
addx.l d0,\1
lsr.l #1,\1
addx.l d0,\1
lsl.l #2,\1
endm
apalin macro ; align allocation pointer
lalin ap
endm
wapalin macro ; word align allocation pointer
walin ap
endm
dpalin macro ; align dictionary pointer
lalin dp
endm
wdpalin macro ; word align dictionary pointer
walin dp
endm
;--- Relative and Absolute Addressing
krn2abs macro ; convert a resident kernel image addr token in \1 to abs addr
lsl.l #1,\1 ; \1 must be a data reg
add.l cp,\1
endm
cod2abs macro ; convert a local image code addr token in \1 to abs addr
lsl.l #1,\1 ; \1 must be a data reg
add.l np,\1
endm
dat2abs macro ; convert a local image data addr in \1 to abs addr
add.l bp,\1
endm
abs2krn macro ; convert abs addr in \1 to resident kernel image addr token
sub.l cp,\1
lsr.l #1,\1 ; \1 must be a data reg
ori.l #kernbit,\1
endm
abs2cod macro ; convert abs addr in \1 to local image code addr token
sub.l np,\1
lsr.l #1,\1 ; \1 must be a data reg
endm
abs2dat macro ; convert a local image data addr in \1 to abs addr
sub.l bp,\1
endm
;--- Dictionary and Data Management
dicp macro ; get the local dictionary pointer
push dp ; to the top of the stack
endm
datp macro ; get the local dataseg pointer
push ap ; to the top of stack
endm
;-----------------------------------------------------------------------;
; Link Fields will be offsets just like execution tokens, masked in ;
; the same manner: right-shifted one bit and masked with $80000000 ;
; if they reside in the kernel, unmasked in D31 if they are in the ;
; local code image. ;
;-----------------------------------------------------------------------;
lfa macro ; create link field in specified thread
dc.l link\1
link\1 set ((((*-start)-4)>>1)|kernbit) ; reset the specified link
endm
nfa macro ; create name field, count & last char |$80
ifeq narg-3
dc.b \1|namebit,\2,(\3|namebit) ; ct, string, nth char
else
dc.b \1|namebit,(\2|namebit) ; ct, sole char
endc
cnop 2 ; word-align start of word
endm ; the above may become longword-align for 68020/30
nfi macro ; create IMMEDIATE name field count & last char |$80
ifeq narg-3
dc.b \1|namebit|immedbit,\2,(\3|namebit) ; ct, string, nth char
else
dc.b \1|namebit|immedbit,(\2|namebit) ; ct, sole char
endc
cnop 2 ; word-align start of word
endm ; the above may become longword-align for 68020/30
headerless macro ; so Headerless defs may be recognized by decompiler
dc.l -1
endm
exetok macro ; execution token in D0, jump to correct machine addr
lsl.l #1,d0 ; msb set indicates a kernel token
bcc.s 1$ ; branch if carry indicates local token
jmp 0(cp,d0.l) ; interpret token as a kernel address
1$ jmp 0(np,d0.l) ; interpret token as a local address
endm
dereftok macro ; \1 is register containing token
move.l \1,d0 ; copy to a shift-able register
lsl.l #1,d0 ; shift out kernel/local bit
bcc.s 8$ ; branch if carry indicates local token
add.l cp,d0 ; convert kernel token to absolute address
bra.s 9$
8$ add.l np,d0 ; convert local token to absolute address
9$ move.l d0,\1
endm
*--- Counted String Assembly
;-----------------------------------------------------------------------;
; Note that the handling of counted strings in the kernel will be ;
; different from the handling of same in the runttime system. BASIS12 ;
; is somewhat ambiguous about the location of the strings compiled by ;
; '"' (quote) ... my intent is that the runtime system will compile ;
; them into data space so they may be altered. (The code segment will ;
; not be generally readable with "@", etc., nor will the kernel). ;
;-----------------------------------------------------------------------;
countstr macro ; "a string" is arg \1
dc.b (1$-(*+1)) ; count byte
dc.b \1 ; compile string
1$ cnop 2 ; align dictionary
endm
*--- Allocating storage in the local image data segment
dataptr set 0 ; keeps track of our local dataseg usage
;--- Perform assembly-time allocation of slots in the local dataseg
; which will be constructed/loaded at runtime
allocdat macro
dataptr set dataptr+\1 ; \1 is number of bytes
endm
setdat macro ; perform allocation as above and SET symbol
\1 set dataptr ; \1 is symbolic name
allocdat \2 ; \2 is amount of storage
endm
avar macro ; make a variable allocation
setdat \1,cellsize ; assign offset
endm
avoc macro ; make a vocabulary allocation
setdat \1,vocwidth+cellsize ; one cell extra for backlink
endm
*--- Default variables in each image's data seg
avar empty ; holds image dictionary size
avar there ; holds image data size
setdat contextarray,contextsize ; the CONTEXT array
avar stdout ; I/O handle loaded by startup
avar stdin ; ditto
avar appwin ; -1 = opened NEWCON: 0 = stdio n = custom win
setdat emitbuf,emitbufsize ; holds chars for output
avar base ; holds numeric base
avar doslib ; holds DOS libptr
avar execlib ; holds Exec libptr
avoc forthvoc ; the FORTH voc thread array
avoc impvoc ; the IMPLEMENTOR voc thread array
avar spzero ; hold initial stack pointer passed by AmigaDOS
avar rpzero ; hold initial return stack allocated at Forth startup
* avar rpsize ; hold user request for rstacksize at next load
avar savedimage ; holds various info for a saved image
avar autostart ; holds autostart vector for a saved image
avar state ; compiling or interpreting?
avar span ; count returned by EXPECT
avar ticktib ; holds address of Terminal Input Buffer
setdat tickword,tibsize ; WORD buffer \ s.b. a MEMALLOC
setdat tibuf,tibsize ; Terminal Input Buffer \ ditto above
setdat sqbuff,tibsize ; Holds interpreted S" strings
avar numtib ; number of chars read into terminal input buffer
avar toin ; input pointer indexing thru TIB
setdat argarray,argarraysize ; holds reg args for OSCalls
avar blk ; tells which BLOCK being interp'ed or 0 for terminal
avar last ; last word in any wordlist added to dictionary
avar width ; holds max num chars <32 to be saved in name fields
avar hld ; holds number conversion string inset
avar dpl ; holds decimal point place of last number parse
avar endq ; true if at end of input line
avar caps ; true if all input should be converted to uppercase
avar istype ; holds deferral for TYPE
avar isemit ; holds deferral for EMIT
avar iswhere ; holds deferral for WHERE
avar isqerror ; holds deferral for ?ERROR
avar catcher ; head of linked list for CATCH/THROW
setdat datestamp,dstampsize ; holds AmigaDOS DateStamp() return
avar current ; holds CURRENT vocabulary
avar tickreadbuff ; holds abs addr of fileread buffer
avar tickblockbuff ; holds abs addr of base of block buffers
avar csp ; holds stack depth during compilation
avar blockfid ; holds BLOCK file identifier
avar sourcefile ; holds source file identifier
avar nonaming ; TRUE if a :NONAME def is under composition
avar voclink ; holds pointer to last vocab declared
avar memtype ; holds allocation type for mem allocs
avar lastblk ; holds index of most-recently-used BLOCK
avar scr ; holds current SCReen number
*--- End of File